package com.dlc.shop.multishop.controller;

import cn.hutool.core.util.PhoneUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Maps;
import com.dlc.shop.allinpay.service.AllinpayCompanyService;
import com.dlc.shop.bean.app.dto.ShopHeadInfoDto;
import com.dlc.shop.bean.enums.*;
import com.dlc.shop.bean.event.EsProductUpdateEvent;
import com.dlc.shop.bean.model.*;
import com.dlc.shop.bean.param.OfflineHandleEventAuditParam;
import com.dlc.shop.bean.param.ShopDetailParam;
import com.dlc.shop.bean.vo.ShopStatusInfoVO;
import com.dlc.shop.common.bean.SysServiceConfig;
import com.dlc.shop.common.config.Constant;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.response.ServerResponseEntity;
import com.dlc.shop.common.util.BeanUtil;
import com.dlc.shop.dao.ShopDetailMapper;
import com.dlc.shop.jky.common.foreign.service.ForeignShopService;
import com.dlc.shop.security.multishop.util.SecurityUtils;
import com.dlc.shop.service.*;
import com.dlc.shop.sys.common.model.ShopEmployee;
import com.dlc.shop.sys.common.service.ShopEmployeeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.Objects;


/**
 * @author lgh on 2018/08/29.
 */
@RestController
@RequestMapping("/shop/shopDetail")
@Tag(name = "店铺基本信息接口")
@AllArgsConstructor
public class ShopDetailController {

    private final ShopDetailService shopDetailService;
    private final ShopEmployeeService shopEmployeeService;
    private final OfflineHandleEventService offlineHandleEventService;
    private final SmsLogService smsLogService;
    private final ShopAuditingService shopAuditingService;
    private final SysConfigService sysConfigService;
    private final UserCollectionShopService userCollectionShopService;
    private final ProductService productService;
    private final ApplicationEventPublisher eventPublisher;
    private final AllinpayCompanyService allinpayCompanyService;
    private final ShopDetailMapper shopDetailMapper;
    private final ForeignShopService foreignShopService;


    @GetMapping("/info")
    @Operation(summary = "获取店铺基本信息", description = "获取店铺基本信息")
    public ServerResponseEntity<ShopDetail> info() {
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(SecurityUtils.getShopUser().getShopId());
        ShopEmployee shopEmployee = shopEmployeeService.getShopEmployeeById(SecurityUtils.getShopUser().getEmployeeId());
        shopDetail.setUserName(shopEmployee.getUsername());
        shopDetail.setMerchantAccount(shopEmployee.getMobile());
        shopDetail.setAccountStatus(shopEmployee.getStatus());
        shopDetail.setEmployeeId(SecurityUtils.getShopUser().getEmployeeId());
        if (Objects.nonNull(shopDetail.getTel())) {
            shopDetail.setTel(PhoneUtil.hideBetween(shopDetail.getTel()).toString());
        }
        // 补充店铺超管手机号
        shopEmployee = shopEmployeeService.getMerchantInfoByShopId(shopDetail.getShopId());
        if (!Objects.isNull(shopEmployee)) {
            if (!ObjectUtils.isEmpty(shopEmployee.getMobile())) {
                shopDetail.setAdminMobile(PhoneUtil.hideBetween(shopEmployee.getMobile()).toString());
            }
        }
        return ServerResponseEntity.success(shopDetail);
    }

    @GetMapping("/getShopInfo")
    @Operation(summary = "店铺信息（装修）", description = "获取的店铺信息（装修）")
    @PreAuthorize("@pms.hasPermission('shop:shopDetail:info')")
    public ServerResponseEntity<ShopHeadInfoDto> getShopInfo() {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(SecurityUtils.getShopUser().getShopId());
        ShopHeadInfoDto shopHeadInfoDto = BeanUtil.map(shopDetail, ShopHeadInfoDto.class);
        // 补充粉丝数量
        long fansCount = userCollectionShopService.count(new LambdaQueryWrapper<UserCollectionShop>()
                .eq(UserCollectionShop::getShopId, shopId));
        shopHeadInfoDto.setFansCount(fansCount);
        // 补充在售商品数量
        long onSaleProdCount = productService.count(new LambdaQueryWrapper<Product>().eq(Product::getShopId, shopId).eq(Product::getStatus, ProdStatusEnums.NORMAL.getValue()));
        shopHeadInfoDto.setProdCount(onSaleProdCount);
        return ServerResponseEntity.success(shopHeadInfoDto);
    }

    @GetMapping("/getStatusInfo")
    @Operation(summary = "获取店铺状态信息", description = "获取店铺状态信息")
    @PreAuthorize("@pms.hasPermission('shop:shopDetail:info')")
    public ServerResponseEntity<ShopStatusInfoVO> getShopStatusInfo() {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopId);
        if (Objects.isNull(shopDetail)) {
            throw new YamiShopBindException("店铺不存在");
        }
        ShopStatusInfoVO shopStatusInfoVO = new ShopStatusInfoVO();
        shopStatusInfoVO.setShopStatus(shopDetail.getShopStatus());
        shopStatusInfoVO.setContractStartTime(shopDetail.getContractStartTime());
        shopStatusInfoVO.setContractEndTime(shopDetail.getContractEndTime());
        if (Objects.equals(shopDetail.getShopStatus(), ShopStatus.OFFLINE.value())) {
            OfflineHandleEvent offlineHandleEventRes = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.SHOP.getValue(), shopId);
            if (Objects.nonNull(offlineHandleEventRes)) {
                shopStatusInfoVO.setOfflineStatus(offlineHandleEventRes.getStatus());
                shopStatusInfoVO.setOfflineReason(offlineHandleEventRes.getOfflineReason());
            } else {
                shopStatusInfoVO.setOfflineReason("平台开启通联支付，请重新提交工商信息与财务信息");
            }
        }
        return ServerResponseEntity.success(shopStatusInfoVO);
    }

    @PutMapping
    @Operation(summary = "更新店铺基本信息", description = "更新店铺基本信息")
    @PreAuthorize("@pms.hasPermission('shop:shopDetail:save')")
    public ServerResponseEntity<Void> update(@Valid @RequestBody ShopDetailParam shopDetailParam) {
        ShopDetail shopDetail = BeanUtil.map(shopDetailParam, ShopDetail.class);
        Long shopId = SecurityUtils.getShopUser().getShopId();
        shopDetail.setShopId(shopId);
        shopDetail.setUpdateTime(new Date());
        ShopAuditing shopAuditing = shopAuditingService.getOne(Wrappers.lambdaQuery(ShopAuditing.class).eq(ShopAuditing::getShopId, shopId));
        if (Objects.nonNull(shopAuditing) && Objects.equals(shopAuditing.getStatus(), AuditStatus.WAITAUDIT.value())) {
            throw new YamiShopBindException("yami.product.shop.AUDIT");
        }
        this.dealWithUpdateOrCreateInfo(shopDetail);
        // 修改店铺接收手机号在专门的接口
        shopDetailService.updateShopDetail(shopDetail);
        eventPublisher.publishEvent(new EsProductUpdateEvent(shopDetail.getShopId(), null, EsOperationType.UPDATE_BY_SHOP_ID));
        return ServerResponseEntity.success();
    }

    @PutMapping("/updateMobile")
    @Operation(summary = "修改店铺接收手机号", description = "修改店铺接收手机号")
    @PreAuthorize("@pms.hasPermission('shop:shopDetail:update')")
    public ServerResponseEntity<Void> updateMobile(@RequestBody ShopDetail shopDetail) {
        shopDetail.setShopId(SecurityUtils.getShopUser().getShopId());
        shopDetail.setUpdateTime(new Date());
        this.dealWithUpdateOrCreateInfo(shopDetail);
        shopDetailService.updateShopDetail(shopDetail);
        return ServerResponseEntity.success();
    }

    @GetMapping("/getOfflineHandleEvent")
    @Operation(summary = "获取店铺下线信息", description = "获取店铺下线信息")
    @PreAuthorize("@pms.hasPermission('shop:shopDetail:info')")
    public ServerResponseEntity<OfflineHandleEvent> getOfflineHandleEventByShopId() {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        OfflineHandleEvent offlineHandleEvent = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.SHOP.getValue(), shopId);
        return ServerResponseEntity.success(offlineHandleEvent);
    }

    @PostMapping("/auditApply")
    @Operation(summary = "违规店铺重新提交审核", description = "违规店铺重新提交审核")
    @PreAuthorize("@pms.hasPermission('shop:shopDetail:applyOnline')")
    public ServerResponseEntity<Void> auditApply(@RequestBody OfflineHandleEventAuditParam offlineHandleEventAuditParam) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        shopDetailService.auditApply(offlineHandleEventAuditParam.getEventId(), shopId, offlineHandleEventAuditParam.getReapplyReason());

        //调用国外请求
        offlineHandleEventAuditParam.setHandleId(shopId);
        foreignShopService.auditApply(offlineHandleEventAuditParam);

        return ServerResponseEntity.success();
    }

    @PostMapping("/sendCode")
    @Operation(summary = "给店长发送验证码", description = "给店长发送验证码")
    public ServerResponseEntity<String> sendLoginCode() {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        // 查询店长信息
        ShopEmployee employee = shopEmployeeService.getMerchantInfoByShopId(shopId);
        if (Objects.isNull(employee.getMobile())) {
            throw new YamiShopBindException("请先为商家账号设置接受通知手机号");
        }
        smsLogService.sendSms(SendType.CAPTCHA, shopId.toString(), employee.getMobile(), Maps.newLinkedHashMap());
        return ServerResponseEntity.success(employee.getMobile());
    }

    @GetMapping("/getAuditingInfo")
    @Operation(summary = "获取店铺审核状态信息", description = "获取店铺审核状态信息")
    @PreAuthorize("@pms.hasPermission('shop:shopDetail:info')")
    public ServerResponseEntity<ShopAuditing> getAuditingInfo() {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        ShopAuditing shopAuditing = shopAuditingService.getOne(Wrappers.lambdaQuery(ShopAuditing.class).eq(ShopAuditing::getShopId, shopId));
        ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopId);
        // 开店协议开关
        SysServiceConfig sysConfigObject = sysConfigService.getSysConfigObject(Constant.SERVICE_SWITCH_CONFIG, SysServiceConfig.class);
        if (Objects.isNull(shopAuditing)) {
            // 审核信息不存在，店铺未提交审核
            shopAuditing = new ShopAuditing();
            shopAuditing.setStatus(AuditStatus.UNCOMMIT.value());
            shopAuditing.setShopProtocolSwitch(sysConfigObject.getShopProtocolSwitch());
            return ServerResponseEntity.success(shopAuditing);
        }
        if (Objects.equals(shopDetail.getShopStatus(), ShopStatus.OFFLINE.value())) {
            shopAuditing.setStatus(ShopStatus.OFFLINE.value());
        } else if (Objects.equals(shopDetail.getShopStatus(), ShopStatus.OFFLINE_AUDIT.value())) {
            if (!allinpayCompanyService.getIsAllinpay()) {
                shopAuditing.setStatus(AuditStatus.WAITAUDIT.value());
            }
        }
        return ServerResponseEntity.success(shopAuditing);
    }

    @GetMapping("/getCode")
    @Operation(summary = "测试用例--接口获取验证码", description = "测试用例--接口获取验证码")
    public ServerResponseEntity<String> getCode(Integer type) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        ShopDetail shopDetail = shopDetailService.getById(shopId);
        SmsLog smsLog = smsLogService.getOne(new LambdaQueryWrapper<SmsLog>()
                .eq(SmsLog::getType, type)
                .eq(SmsLog::getUserPhone, shopDetail.getTel())
                .eq(SmsLog::getStatus, 1));
        return ServerResponseEntity.success(smsLog.getMobileCode());
    }

    @PostMapping("/createAllinpayMember")
    @Operation(summary = "给还没有创建通联账户的商家创建一个", description = "给还没有创建通联账户的商家创建一个")
    public ServerResponseEntity<Void> createAllinpayMemberByShopId() {
        shopDetailService.createAllinpayMemberByShopId(SecurityUtils.getShopUser().getShopId());
        shopDetailService.removeShopDetailCacheByShopId(SecurityUtils.getShopUser().getShopId());
        return ServerResponseEntity.success();
    }

    @PutMapping("/updateAcctProtocolNo")
    @Operation(summary = "更新店铺账户协议编号")
    @Parameters({
            @Parameter(name = "signAcctType", description = "签约类型 1.个人 2.法人 3.企业"),
            @Parameter(name = "acctProtocolNo", description = "账户提现协议编号")
    })
    @PreAuthorize("@pms.hasPermission('shop:shopDetail:update')")
    public ServerResponseEntity<Void> updateAcctProtocolNo(@RequestParam("signAcctType") Integer signAcctType,
                                                           @RequestParam("acctProtocolNo") String acctProtocolNo) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        // 企业会员-“企业名称”“法人姓名”变更后，需重新签约。
        shopDetailMapper.updateAcctProtocolNoByType(shopId, signAcctType, acctProtocolNo);
        shopDetailService.removeShopDetailCacheByShopId(shopId);
        return ServerResponseEntity.success();
    }


    /**
     * 处理店铺信息，这些信息商家无法直接修改
     *
     * @param shopDetail
     */
    private void dealWithUpdateOrCreateInfo(ShopDetail shopDetail) {
        if (Objects.isNull(shopDetail)) {
            return;
        }
        shopDetail.setContractEndTime(null);
        shopDetail.setContractStartTime(null);
        shopDetail.setShopStatus(null);
        shopDetail.setType(null);
        shopDetail.setIsSupplier(null);
    }

}
